import 'package:dio/dio.dart';

class HttpLogInterceptor extends Interceptor {
  static int _limitLength = 800;
  static String deviceName = "";
  static String deviceVersion= "";
  static String identifier ="";
  HttpLogInterceptor({
    // this.dioState = "POST",
    this.request = true,
    this.requestHeader = true,
    this.requestBody = true,
    this.responseHeader = false,
    this.responseBody = true,
    this.dataEncode = false,
    this.timeOut = false,
    this.error = true,
    this.logPrint = print,
  });

  // // dio 网络状态
  // String dioState;

  /// Print request [Options]
  bool request;

  /// Print request header [Options.headers]
  bool requestHeader;

  /// Print request data [Options.data]
  bool requestBody;

  /// Print [Response.data]
  bool responseBody;

  /// Print [Response.headers]
  bool responseHeader;

  /// Print error message
  bool error;

  /// 是否需要解码data数据
  bool dataEncode;

  ///是否打印超时时间
  bool timeOut;

  /// Log printer; defaults print log to console.
  /// In flutter, you'd better use debugPrint.
  /// you can also write log in a file, for example:
  ///```dart
  ///  var file=File("./log.txt");
  ///  var sink=file.openWrite();
  ///  dio.interceptors.add(LogInterceptor(logPrint: sink.writeln));
  ///  ...
  ///  await sink.close();
  ///```
  void Function(String? object) logPrint;

  @override
  Future onRequest(RequestOptions options,
      RequestInterceptorHandler handler) async {
    logPrint('************  请求体开始  ************');
    _printKV('uri', options.uri);
    if(responseHeader){
      _printKV('content-type', () => options.contentType);
      _printKV('Accept', () => options.contentType);
      _printKV('credentials', () => 'include');
    }
    if (requestHeader) {
      options.headers.forEach((key, v) => _printKV(' $key', v));
    }
    if (requestBody) {
      logPrint('data:${options.headers}');
      _printAll(options.data, request: true);
    }
    logPrint('************  请求体结束  ************\n\n');
    return handler.next(options);
  }

  @override
  Future onError(DioError err, ErrorInterceptorHandler handler) async {
    if (error) {
      logPrint('************  DioError开始  ************');
      logPrint('uri: ${err.requestOptions.uri}');
      logPrint('statusCode: ${err.response?.statusCode}');
      logPrint('error: $err');
      if (err.response != null) {
        _printResponse(err.response, error: true);
      }
      logPrint('************  DioError结束  ************\n\n');
    }
    return handler.next(err);
  }

  @override
  Future onResponse(Response response,
      ResponseInterceptorHandler handler) async {
    logPrint('************  结果体开始  ************');
    _printResponse(response);
    return handler.next(response);
  }

  Future<void> _printResponse(Response? response, {bool error = false}) async {
    _printKV('uri', response?.requestOptions.uri);
    if (responseHeader) {
      _printKV('content-type', () => response?.requestOptions.contentType);
      _printKV('Accept', () => response?.requestOptions.contentType);
      _printKV('Authorization', () => response?.requestOptions.contentType);
      _printKV('credentials', () => 'include');
      _printKV('qb-app-version', '');
    }
    if (responseBody) {
      logPrint('Response Text:');
      _printAll(response.toString());
    }
    if (!error) {
      logPrint('************  结果体结束  ************\n\n');
    }
  }

  void _printKV(String key, Object? v) {
    logPrint('$key--> $v');
  }

  void _printAll(msg, {bool request = false}) {
    if (request) {
      msg.toString().split('\n').forEach(logPrint);
    } else {
      var result = msg;
      try {
        //result = '解析成功：${json.decode(msg)}';
        result = '解析成功:$msg}';
      } catch (e) {
        result = '解析失败:${msg}';
      }
      result.toString().split('\n').forEach((element) {
        if (element.length < _limitLength) {
          _printKV('Part', element);
        } else {
          _segmentationLog(element);
        }
      });
    }
  }

  void _segmentationLog(String msg) {
    var outStr = StringBuffer();
    for (var index = 0; index < msg.length; index++) {
      outStr.write(msg[index]);
      if (index % _limitLength == 0 && index != 0) {
        _printKV('Part', outStr);
        outStr.clear();
        var lastIndex = index + 1;
        if (msg.length - lastIndex < _limitLength) {
          var remainderStr = msg.substring(lastIndex, msg.length);
          _printKV('Part', remainderStr);
          break;
        }
      }
    }
  }
}
